t Subclasses, Inheritance, and Attribute Overshadowing*1023*
An animal kingdom based on one generic animal type is not too exciting, however. A flurry of subclassing activity can take care of the situation.
u Activate the Classes window and zoom it to full screen to give your Animal class hierarchy some room to grow. Select the Animal class icon and Command-option-click a new class below and to the left of Animal. Name the new class Bird.
You have just created a subclass of the Animal class. Animal is the*821* parent or*1027* superclass of Bird. The line connecting the two classes is an*480* inheritance link.
 
The object-oriented feature of inheritance provides that subclasses are created with at least all the attributes of the parent or superclass.
u Open the Attributes window of the Animal class, and then open the Attributes window of Bird (you may need to resize the Classes window). Notice that subclass attributes are the same in number, name, and default values as the parent’s attributes. The fact that the Bird class’s attributes are inherited is reflected in the downward-pointing arrow in the attribute icons of Bird.
u Subclasses can have their own attributes in addition to those inherited. Click to create a new attribute below food in the Bird Attributes window and name it wingspan. Notice that attributes defined in the subclass are represented by a plain triangular attribute icon without the inheritance arrow.
 
u Subclasses can themselves be parents to other subclasses, which in turn can be parents, and so on. Activate the Classes window and create two subclasses of Bird. Name one Chicken and the other Duck.
NOTE: You can create unattached classes by Command-clicking in open space in the Classes window. To then create an inheritance relationship, click first on the class that is to be the parent, Option-drag a rubber-banding inheritance link, and then click the subclass icon to “nail” the link in place.
If you accidentally stretch an inheritance link from the intended subclass back to its parent, the parent’s own inheritance relationship, if any, is dissolved. The intended subclass becomes the parent of the class that was supposed to be the parent. If you inadvertently make such a reverse connection, simply reconnect the inheritance link from the parent class of the class you would like to make a parent and itself. After reestablishing the grandparent-to-parent inheritance relationship, you can then connect the inheritance link from the intended parent to the new subclass. If the intended parent had no parent, simply select the intended parent and Option-drag-click the inheritance link to the intended subclass. Open the Attributes windows for both classes to confirm which class is contributing its attributes to the other.
u To complete the taxonomy of species with which to populate the barnyard, add subclasses until your Animal Class Hierarchy looks like this:
 
If you open an attribute window for any of your subclasses, you see inherited name, age, and food attributes. In addition, the Chicken and Duck classes inherited the wingspan attribute from their Bird parent class along with the rest of the attributes from Bird’s own parent, Animal. If you now added a new attribute to Animal, it would simultaneously appear as an attribute in all the Animal subclasses.
u Inherited attributes cannot be deleted. Select the age attribute icon of the Bird class and press Command-D. Nothing happens; the attribute remains. If you try the same command on wingspan in class Bird, you will have to recreate it after its icon disappears from the attribute window.
While attributes are inherited, their inherited default values can be overridden—your animals do not all have to eat "generic chow", for example. This is an object-oriented feature called*87* attribute overshadowing.*816*
u Inspect and further practice editing attribute values by opening a Value window on the food attribute of each of your Animal subclasses and edit them as follows (or use whatever you would like Farmer Brown to feed his animals):
Chicken food: chicken feed
Duck food: bread crumbs
Dog food: ground liver parts
Cat food: fish heads
Guernsey food: grass
Black Angus food: steer feed
Horse food: oats and barley
While you are editing food attributes, experiment by adding instance attributes to classes in the hierarchy. Notice how these additional attributes are inherited along the inheritance links.
Class attributes are inherited just like instance attributes.
u Assume cows are gregarious and intelligent—they hang around in a herd and all know each other. Add a herdMembers class attribute (not an instance attribute) to the Cow class. Once added, this class attribute is inherited by both Cow subclasses. You can confirm this by inspecting the attributes window of the Black Angus class.
 
An inherited class-attribute icon displays the downward inheritance arrow just like an inherited instance attribute. And like its instance counterpart, an inherited*478* class attribute cannot be deleted from a subclass.
You now have a rather broad range of animal types that can inhabit the Farmer’s barnyard.
u Open the activeYards class attribute of Barnyard class. Then open a Value window on the Barnyard instance, which is the only item in the activeYards list.
u Open the inhabitants attribute of the Barnyard instance and delete the generic Animal instances that you ran previously in the simulation.
u Add Chicken, Duck, Dog, Black Angus, and Horse instances to the list of inhabitants. Remember to first deposit a NULL list item and then open its value window to select the animal instance into which you want to transform the NULL item. Give each instance a name and age. And change the default favorite food of the species to a foodstuff particularly liked by the individual—Rover, the Dog, may like beef by-products rather than ground liver, for example. Your starting community in the activeYards Barnyard instance now looks like this:
 
u Close the Value of Attribute inhabitants window and open a Value window on the diary attribute. Delete all instances of DiaryEntry from the diary attribute. Close the Value of Attribute diary window. Option-click OK to dismiss all Value windows.
You are now primed with a new community of inhabitants in the activeYards’ Barnyard instance.
u Run the simulation, adding instances of real species as opposed to generic animals, and watch what happens. A typical diary entry looks something like this:
 
At first glance, this is not too surprising. Not much has changed, with the exception of the diversity of foodstuffs the animals consume. But how do all these instances of Animal subclasses know how to eat, sleep, move, talk, and have birthdays?
t Method Inheritance and Overshadowing
Method inheritance, like attribute inheritance, is a mechanism at work in the relationship between parent classes and their subclasses.
u To confirm your suspicion of method inheritance, stop running the simulation and open the Methods*713* window*727* of the Dog class.
 
Whoa! No method icons here to indicate why Rover knows what he knows.
u Select Classes from the ˙Info… *451*dialog. Select Dog in the scrolling list of classes and select Methods. And there you have it—a Dog instance knows five methods.
 
A little investigation reveals that the five generic methods known to the Dog class are those of the original Animal class. Every subclass of Animal has access to the methods of its parent and grandparents.
NOTE: Inherited methods do not show up in the Methods window of a subclass. Only methods specifically defined in a class have a method icon in the Methods window for that class. To get a complete picture of what methods are known to a specific class, select the class in the ˙Info… dialog and then select Methods. The dialog lists both inherited and class-specific methods available to instances of the selected class.
So the barnyard is beginning to show a little diversity. Different kinds of animals are eating different kinds of food. But dogs bark, cats meow, horses gallop, and ducks waddle. Behavioral diversity is the subject of the next phase of elaboration of the Barnyard Simulation.
Method inheritance is great for efficiency when subclasses behave the same as their parents. But when diversity is required, you can override inheritance by giving a subclass a new method with the same name as a method of its parent. In object-oriented programming terminology, a language exhibits polymorphism*832* when multiple classes, even unrelated ones, can each have its own method with a name that is also defined in the other classes.
In an object-oriented office-automation application, for example, if you can ask a Memo object and a Report object to print, they produce entirely different results. The Memo and Report classes each have a print method defined, but what each method does is unique.
Further, both Memo and Report are subclasses of Hardcopy, which has its own unique print method. Memo uses its parent print method unchanged (just as your Animal subclasses are currently using the methods of the Animal class). Report class, on the other hand, outputs a more complex, formatted document requiring it to have its own, more elaborate print method.
 
Prograph’s inheritance feature allows Memo to use its parent’s print method, while polymorphism allows Report to have its own version of the print method. When you use this polymorphic characteristic of Prograph classes, you overshadow*689* an inherited method. (Further, polymorphically speaking, any class, even one unrelated to Hardcopy, can have a print method.)
Method overshadowing lets you give your Animal subclasses their own style of talking and moving.
u Open the Chicken Methods window and create a talk method.
u Open the Chicken/talk method. To give a Chicken instance its appropriate sound, create the following case (to make life easier, you can copy and paste the talk method from the Animal class, and then edit it):
 
u The string constant input to the "join" operation should read: " says, “Cluck, cluck." " Enter this string constant and then double-click on it to open a Change Value dialog. Make sure that the string has a leading and a trailing space. Also, you should use the typographic quotation marks, “ ” (Option-[ and Shift-Option-[), since Prograph uses the *931*quotation-mark character ( " ) to *1017*delimit string elements.
 
u Close the Change Value dialog and case window to the Chicken/talk method. Use the above process to overshadow*690* the talk method in other Animal subclasses. Make instances of these subclasses talk as follows:
A Duck instance " says, “Quack, quack.” "
A Dog instance " says, “Bow wow wow.” "
A Cat instance " says, “Meow, purr purr.” "
A Cow instance " says, “Moooooo.” "
A Horse instance " says, “Nay.” "
u Do the same method-overshadowing procedure with the Animal/move method. Make each of the subclasses have its own move method as follows:
A Chicken instance " struts around the yard. "
A Duck instance " waddles around the yard. "
A Cat instance " slinks around the yard. "
A Horse instance " trots around the yard. "
By not overshadowing the move method of the Dog and Cow classes, instances of these subclasses still walk around the yard as provided by the generic move method in the Animal class.
The Barnyard Simulation is now ready for another run. This time you see even more diversity in the eating, speaking, and locomotion behaviors of the yard’s inhabitants.
u Optionally, you may want to open the Barnyard instance in the activeYards class attribute of the Barnyard class and delete all the old DiaryEntry items in the diary attribute to establish a clean starting point from which to study the current yard’s behavior.
u Run the simulation for a number of time-slice cycles and observe the new diversity of entries in the diary reports. A typical entry reflects behavioral variation as a result of your attribute- and method-overshadowing activity above.
 
While these exercises are rather simple, your Barnyard Simulation is shaping up into an elaborate class structure with diverse attribute sets using overshadowing*691* of inherited attributes and methods. Inheritance*477* provides a means of code and data-structure sharing, a form of “programming of exceptions”: subclasses need only be explicitly specified in the areas in which their attribute structure or methods of behavior differ from their parents.